package com.voice.server.service.impl;

import com.voice.server.command.impl.MatchTextCommand;
import com.voice.server.connection.ConnectionInvoke;
import com.voice.server.converter.DeviceConverter;
import com.voice.server.entity.Device;
import com.voice.server.enums.PushTypeEnum;
import com.voice.server.enums.ResultEnum;
import com.voice.server.exception.SystemException;
import com.voice.server.input.DeviceQuery;
import com.voice.server.input.DeviceUpdateRequest;
import com.voice.server.job.DeviceWorkScheduler;
import com.voice.server.observer.impl.CmdObservable;
import com.voice.server.output.DeviceInfo;
import com.voice.server.repository.DeviceRepository;
import com.voice.server.service.DeviceService;
import com.wangjiacai.hqlQuery.service.impl.BaseServiceImpl;
import com.wangjiacai.hqlQuery.util.HqlUtil;
import com.wangjiacai.utils.utils.BeanUtil;
import com.wangjiacai.utils.web.service.AsyncService;
import com.wangjiacai.utils.web.service.RedisService;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

/*
 * @auther: wangjiacai
 *
 * @create: 2019-01-27 18:09:41
 */
@Service
public class DeviceServiceImpl extends BaseServiceImpl implements DeviceService {

    @Autowired
    private DeviceRepository deviceRepository;
    @Autowired
    private DeviceConverter deviceConverter;
    @Autowired
    private RedisService redisService;
    @Autowired
    private DeviceWorkScheduler deviceWorkScheduler;
    @Autowired
    private ConnectionInvoke connectionInvoke;
    @Autowired
    private AsyncService asyncService;

    @Override
    public long getDeviceListNum(DeviceQuery deviceQuery) {
        return this.count(HqlUtil.getCountHql(deviceQuery), deviceQuery);
    }

    @Override
    public List<DeviceInfo> getDeviceList(DeviceQuery deviceQuery, Pageable pageable) {
        List<Device> list = this.find(HqlUtil.getQueryHql(deviceQuery), deviceQuery, pageable, Device.class);
        return deviceConverter.converterToListSync(list);
    }


    @Override
    public Device getDeviceByDeviceIdAndUserId(String userId, String deviceId) {
        return deviceRepository.findByUserIdAndId(userId, deviceId);
    }

    @Override
    public void updateDevice(DeviceUpdateRequest deviceUpdateRequest) {
        if (deviceUpdateRequest.getPushType() == PushTypeEnum.TextMatch.getCode()) {
            if (StringUtils.isEmpty(deviceUpdateRequest.getMatchText()))
                throw new SystemException("推送类别为文本匹配推送时，匹配文字不能为空");
        }
        if (StringUtils.isEmpty(deviceUpdateRequest.getStartTime()) && !StringUtils.isEmpty(deviceUpdateRequest.getEndTime())) {
            throw new SystemException("设备工作时间必须是一个时间段，缺少开始时间");
        }
        if (StringUtils.isEmpty(deviceUpdateRequest.getEndTime()) && !StringUtils.isEmpty(deviceUpdateRequest.getStartTime())) {
            throw new SystemException("设备工作时间必须是一个时间段，缺少结束时间");
        }
        Device device = deviceRepository.findByUserIdAndId(deviceUpdateRequest.getUserId(), deviceUpdateRequest.getId());
        BeanUtil.copyProperties(deviceUpdateRequest, device);
        if (device == null) throw new SystemException(ResultEnum.ILLEGAL_USERS);
        asyncService.run(() -> {
            redisService.hashSet(CmdObservable.hashKey, device.getDeviceKey(), device.getPushType());
            connectionInvoke.sendServerMessageToDevice(device.getUserId(),device.getDeviceKey(),device.getPushType());
        });
        if (deviceUpdateRequest.getPushType() == PushTypeEnum.TextMatch.getCode())
            redisService.hashSet(MatchTextCommand.hashKey, device.getDeviceKey(), device.getMatchText());
        try {
            if (!StringUtils.isEmpty(deviceUpdateRequest.getEndTime())) {
                String[] startTime = device.getStartTime().split(":");
                String[] endTime = device.getEndTime().split(":");
                deviceWorkScheduler.startWorkScheduler(device.getUserId(), device.getDeviceKey(), Integer.parseInt(startTime[0]), Integer.parseInt(startTime[1]));
                deviceWorkScheduler.endWorkScheduler(device.getUserId(), device.getDeviceKey(), Integer.parseInt(endTime[0]), Integer.parseInt(endTime[1]));
            } else {
                deviceWorkScheduler.startWorkScheduler(device.getUserId(), device.getDeviceKey());
            }
        } catch (SchedulerException e) {
            throw new SystemException(ResultEnum.SchedulerException);
        }
        deviceRepository.save(device);
    }

}
